package mulegame;

import java.awt.Color;

/**
 * Creates players and sets their basic stats based on race, also can deduct
 * money from their total money based on price of objects.
 * 
 * @author AREA 29
 * 
 */
public class Player {
	private String name = "unset";
	private Race race;
	private Color color;
	private Mule mule;

	private int money, score, food, ore, energy;

	/**
	 * sets name, race, and color, gives diff stats based on race
	 * 
	 * @param name
	 *            player's name
	 * @param race
	 *            player's race
	 * @param col
	 *            player's color
	 */
	public Player(String name, Race race, Color col, GameConfig.Difficulty diff) {
		this.name = name;
		color = col;
		this.race = race;
		money = race.startMoney;
		score = 0;
		switch (diff) {
		case BEGINNER:
			food = 8;
			energy = 4;
			ore = 0;
			break;
		case STANDARD:
			food = 4;
			energy = 2;
			ore = 0;
			break;
		case TOURNAMENT:
			food = 4;
			energy = 2;
			ore = 0;
			break;
		}

	}

	/**
	 * sets player name, race, color, and resources based on a string that is
	 * passed in
	 * 
	 * @param lines
	 *            a string holding player info
	 */
	public Player(String[] lines) {
		Logger.println("making player from definition");
		for (String line : lines) {
			String[] args = line.split("\\s:\\s");
			if (args[0].equals("Name")) {
				name = args[1];
			}
			if (args[0].equals("Race")) {
				switch (Integer.parseInt(args[2])) {
				case 1:
					race = Race.CARIBOUER;
					break;
				case 2:
					race = Race.STARBUCKIAN;
					break;
				case 3:
					race = Race.DUNKINER;
					break;
				case 4:
					race = Race.BEANITE;
					break;
				case 5:
					race = Race.GENERICAN;
					break;
				default:
					Logger.println("Player(String) : unknown race id");
					break;
				}
			}
			if (args[0].equals("Color")) {
				color = new Color(Integer.parseInt(args[2]));
			}
			if (args[0].equals("Money")) {
				money = Integer.parseInt(args[1]);
			}
			if (args[0].equals("Score")) {
				score = Integer.parseInt(args[1]);
			}
			if (args[0].equals("Ore")) {
				ore = Integer.parseInt(args[1]);
			}
			if (args[0].equals("Food")) {
				food = Integer.parseInt(args[1]);
			}
			if (args[0].equals("Energy")) {
				energy = Integer.parseInt(args[1]);
			}
		}
	}

	/**
	 * sets money
	 * 
	 * @param m
	 *            money
	 */
	public void setMoney(int m) {
		money = m;
	}

	/**
	 * returns amount of money
	 * 
	 * @return money
	 */
	public int getMoney() {
		return money;
	}

	/**
	 * sets food
	 * 
	 * @param f
	 *            food
	 */
	public void setFood(int f) {
		food = f;
	}

	/**
	 * sets energy
	 * 
	 * @param e
	 *            energy
	 */
	public void setEnergy(int e) {
		energy = e;
	}

	/**
	 * returns amount of energy
	 * 
	 * @return energy
	 */
	public int getEnergy() {
		return energy;
	}

	/**
	 * sets ore
	 * 
	 * @param o
	 *            ore
	 */
	public void setOre(int o) {
		ore = o;
	}

	/**
	 * returns amount of ore
	 * 
	 * @return ore
	 */
	public int getOre() {
		return ore;
	}

	/**
	 * returns color
	 * 
	 * @return color
	 */
	public Color getColor() {
		return color;
	}

	/**
	 * returns name
	 * 
	 * @return name
	 */
	public String getName() {
		return name;
	}

	/**
	 * returns true if there is more money than the price
	 * 
	 * @param price
	 *            price of object
	 * @return money >= price
	 */
	public boolean canAfford(int price) {
		return money >= price;
	}

	/**
	 * reduces price from total amount of money. Logger prints out message
	 * 
	 * @param price
	 *            price of object
	 */
	public boolean charge(int price) {
		if (canAfford(price)) {
			money -= price;
			// Logger.println("Player " + name + " charged $" + new
			// Integer(price).toString());
			return true;
		} else {
			// Logger.println("Player " + name + " can't afford $" + new
			// Integer(price).toString());
			return false;
		}
	}

	/**
	 * Is paid for an object and updates money. This information is displayed
	 * 
	 * @param price
	 *            price of object
	 */
	public void pay(int price) {
		money += price;
		Logger.println("Player " + name + " paid $"
				+ new Integer(price).toString());
	}

	/**
	 * food is deducted from total amount of player food
	 * 
	 * @param takeAway
	 *            how much to be taken away
	 */
	public void deductFood(int takeAway) {
		food = food - takeAway >= 0 ? food - takeAway : 0;
	}

	/**
	 * returns food of player
	 * 
	 * @return food
	 */
	public int getFood() {
		return food;
	}

	/**
	 * calculates player score and returns it
	 * 
	 * @return score
	 */
	public int getScore() {
		calcScore();
		return score;
	}

	/**
	 * calculates score of player by adding money, food, enerygy, and ore of
	 * player
	 */
	private void calcScore() {
		// TODO implement a more interesting score computation
		// possibly: factor in the amount of land owned?
		score = money + food + energy + ore;
	}

	/**
	 * different player races available
	 * 
	 * @author AREA 29
	 * 
	 */
	public enum Race {
		CARIBOUER("Caribouer", 1000, 1), STARBUCKIAN("StarBuckian", 1600, 2), // Equivalent
																				// of
																				// Flapper
		DUNKINER("Dunkiner", 1000, 3), BEANITE("Beanite", 1000, 4), GENERICAN(
				"Generican", 600, 5); // Equivalent of Human
		/**
		 * sets race name
		 */
		public final String name;
		public final int startMoney;
		public final int id;

		/**
		 * constructs a race
		 * 
		 * @param name
		 * @param money
		 */
		Race(String name, int money, int id) {
			this.name = name;
			startMoney = money;
			this.id = id;
		}
	}

	/**
	 * gets a mule
	 * 
	 * @param m
	 *            mule
	 */
	public void giveMule(Mule m) {
		mule = m;
	}

	/**
	 * mule is taken away, returns mule that was taken away
	 * 
	 * @return ret
	 */
	public Mule takeMule() {
		Mule ret = mule;
		mule = null;
		return ret;
	}

	/**
	 * Given food and amount added to player food. Message printed out to inform
	 * player
	 * 
	 * @param quantity
	 *            quantity of food added
	 */
	public void giveFood(int quantity) {
		// Logger.println(name + " given " + Integer.toString(quantity) +
		// " food");
		food += quantity;
	}

	/**
	 * food taken away. Message printed out to inform player
	 * 
	 * @param quantity
	 *            quantity of food taken away
	 * @return ret
	 */
	public boolean takeFood(int quantity) {
		boolean ret = food >= quantity;
		if (ret) {
			food -= quantity;
			Logger.println(name + " had " + Integer.toString(quantity)
					+ " food taken");
		}
		return ret;
	}

	/**
	 * Given energy and amount added to player energy. Message printed out to
	 * inform player
	 * 
	 * @param quantity
	 *            quantity of energy added
	 */
	public void giveEnergy(int quantity) {
		Logger.println(name + " given " + Integer.toString(quantity)
				+ " energy");
		energy += quantity;
	}

	/**
	 * energy taken away
	 * 
	 * @param quantity
	 *            quantity of energy taken away. Message printed out to inform
	 *            player
	 * @return ret
	 */
	public boolean takeEnergy(int quantity) {
		boolean ret = energy >= quantity;
		if (ret) {
			energy -= quantity;
			Logger.println(name + " had " + Integer.toString(quantity)
					+ " energy taken");
		}
		return ret;
	}

	/**
	 * Given ore and amount added to player ore. Message printed out to inform
	 * player
	 * 
	 * @param quantity
	 *            quantity of ore added
	 */

	public void giveOre(int quantity) {
		Logger.println(name + " given " + Integer.toString(quantity) + " beans");
		ore += quantity;
	}

	/**
	 * ore taken away. Message printed out to inform player
	 * 
	 * @param quantity
	 *            quantity of ore taken away
	 * @return ret
	 */
	public boolean takeOre(int quantity) {
		boolean ret = ore >= quantity;
		if (ret) {
			ore -= quantity;
			Logger.println(name + " had " + Integer.toString(quantity)
					+ " beans taken");
		}
		return ret;
	}

	/**
	 * returns a string with player information about ore, food and energy
	 * 
	 * @return ret
	 */
	public String getStorehouse() {
		return "Ore : " + Integer.toString(ore) + "\nFood : "
				+ Integer.toString(food) + "\nEnergy : "
				+ Integer.toString(energy);
	}

	@Override
	/**
	 * returns a String with player name, race, and color
	 * @return ret
	 */
	public String toString() {
		String ret;
		ret = "Name : " + name + "\n";
		ret += "Race : " + race.name + " : " + Integer.toString(race.id) + "\n";
		String col = "";

		switch (color.getRGB()) {
		case -16777216: // black
			col = "Black";
			break;
		case -65536: // red
			col = "Red";
			break;
		case -1: // white
			col = "White";
			break;
		case -16711936: // green
			col = "Green";
			break;
		case -256: // yellow
			col = "Yellow";
			break;
		default:
			col = "UNKNOWN";
			Logger.println("Unknown color encountered in Player's toString");
			break;
		}
		col += " : " + Integer.toString(color.getRGB());
		ret += "Color : " + col + "\n";
		ret += "Money : " + Integer.toString(money) + "\n";
		ret += "Score : " + Integer.toString(getScore()) + "\n";
		ret += getStorehouse() + "\n";
		return ret;
	}
}
